/**
 * @author Fang Lu, fanglupku@gmail.com
 * 2011-5-22
 */
package com.autotag;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fanglu.util.FileDealer;

import sei.pku.wsdl_analyzer.Endpoint;
import sei.pku.wsdl_analyzer.WSDLFile;
import sei.pku.wsdl_analyzer.WSDLFileAnalyzer;

public class EnvironmentTagGenerator {
	public static final Pattern WSDL_Definition_Pattern = Pattern.compile("(<\\s*wsdl:definition.+?>)|(<\\s*definition.+?>)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
	public static final Pattern WSDL_Declaration_Pattern = Pattern.compile("=\".+?\"", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
	
	public static void main(String args[]){
		//part 1, generate environment tag
		File dirFile = new File("C:\\Users\\ftc\\Desktop\\ICSOC\\WSDL_FILE\\WSDL_FILE");
		File tagFile = new File("C:\\Users\\ftc\\Desktop\\ICSOC\\WSDL_FILE\\result\\env_tag.txt");
		File mapFile = new File("models\\env_mapping.txt");
		generateEnvironmentTag(dirFile, tagFile, mapFile);
//		statDeclaration(dirFile, tagFile);
				
	}
	
	public static void statDeclaration(File dirFile, File outFile){
		File[] files = dirFile.listFiles();
		try {
			FileOutputStream fos = new FileOutputStream(outFile);
			OutputStreamWriter osw = new OutputStreamWriter(fos);
			BufferedWriter bw = new BufferedWriter(osw);
			
			HashMap<String, HashSet<String>> declarationMapUUID = new HashMap<String, HashSet<String>>();
			for (int i=0; i<files.length; ++i){
				File thisFile = files[i];
				bw.write("#");
				bw.write(thisFile.getName());
				bw.write("\n");
				try {
					String content = FileDealer.getFileContent(files[i].getAbsolutePath());
					String defStr = getDefinitionElement(content);
					HashSet<String> thisDeclareSet = getDeclarationSet(defStr);
					
					for (String declaration : thisDeclareSet) {
						declaration = declaration.trim();
						if (declaration.contains("localhost") 
								|| declaration.contains("127.0.0.1")
								|| !declaration.startsWith("http")){
							continue;
						}
						bw.write(declaration);
						bw.write("\n");
						
						HashSet<String> thisUUIDSet = declarationMapUUID.get(declaration);
						if (thisUUIDSet == null){
							thisUUIDSet = new HashSet<String>();
							declarationMapUUID.put(declaration, thisUUIDSet);
						}
						thisUUIDSet.add(thisFile.getName());
					}

//					System.out.println(i + ",ok");
					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			Iterator<String> itor_dec = declarationMapUUID.keySet().iterator();
			while(itor_dec.hasNext()){
				String thisDec = itor_dec.next();
				HashSet<String> thisSet = declarationMapUUID.get(thisDec);
				System.out.println(thisDec + "," + thisSet.size());
			}
			
			bw.close();
			osw.close();
			fos.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static HashSet<String> getDeclarationSet(String definitionString){
		HashSet<String> resultList = new HashSet<String>();
		String strArray [] = definitionString.split("\\s");
		for (int i=0; i<strArray.length; ++i){
			Matcher matcher = WSDL_Declaration_Pattern.matcher(strArray[i]);
			while (matcher.find()){
				String prefix = new String(strArray[i].substring(0,matcher.start()));
				if (prefix.equalsIgnoreCase("matcher.start()")
						||prefix.equalsIgnoreCase("targetNamespace")){
					
				}else{
					String thisDeclaration = new String(strArray[i].substring(matcher.start()+2, matcher.end()-1));
					resultList.add(thisDeclaration);
				}
				
			}
		}
		return resultList;
	}
	
	public static String getDefinitionElement(String wsdlContent){
		String result = "";
		Matcher matcher = WSDL_Definition_Pattern.matcher(wsdlContent);
		if (matcher.find()){
			result = new String(wsdlContent.substring(matcher.start(), matcher.end()));
		}
		return result;
	}
	
	public static HashMap<String, String> initSepcificationMapEnvTag(File mapFile){
		HashMap<String, String> resultMap = new HashMap<String, String>();
		
		try {
			String content = FileDealer.getFileContent(mapFile.getAbsolutePath());
			StringReader sr = new StringReader(content);
			BufferedReader br = new BufferedReader(sr);
			String oneLine = br.readLine();
			while (oneLine != null){
				String[] strArray = oneLine.split("\\s");
				if (strArray != null && strArray.length > 2){
					resultMap.put(strArray[0].trim(), strArray[2].trim());
				}
				oneLine = br.readLine();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return resultMap;
	}
	
	public static void generateEnvironmentTag(File dirFile, File tagFile, File mapFile){
		HashMap<String, String> specMapEnvTag = initSepcificationMapEnvTag(mapFile);
		File[] files = dirFile.listFiles();
		try {
			FileOutputStream fos = new FileOutputStream(tagFile);
			OutputStreamWriter osw = new OutputStreamWriter(fos);
			BufferedWriter bw = new BufferedWriter(osw);
			
			for (int i=0; i<files.length; ++i){
				File thisFile = files[i];
				bw.write("#");
				bw.write(thisFile.getName());
				bw.write("\n");
				try {
					String content = FileDealer.getFileContent(files[i].getAbsolutePath());
					String defStr = getDefinitionElement(content);
					HashSet<String> thisDeclareSet = getDeclarationSet(defStr);
					
					HashSet<String> envTagSet = new HashSet<String>();
					for (String declaration : thisDeclareSet) {
						declaration = declaration.trim();
						String thisTag = specMapEnvTag.get(declaration);
						if (thisTag != null){
							envTagSet.add(thisTag);
						}
					}
					
					for (String thisTag : envTagSet) {
						thisTag = thisTag.trim();
						bw.write(thisTag);
						bw.write("\n");
					}

//					System.out.println(i + ",ok");
					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			bw.close();
			osw.close();
			fos.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
